<template>
  <div :class="isEdit ? '' : 'buttonBox'">
    <div v-if="isEdit != true" class="animationBox">
      <!-- this.owner == 'null' 说明不是委托任务-->
      <div
        v-if="btnLoading == false"
        :class="['outCOn', btnClick ? 'outClick' : 'dieClick']"
        :style="btnClick ? `width: ${defaultBtnMap[1].length * 160}px` : 'width:0px'"
      >
        <!-- 系统按钮 -->
        <a-button
          v-for="(item, index) in defaultBtnMap[1] ? defaultBtnMap[1] : []"
          @click="eventDistribution(item.click_)"
          :key="index"
          :class="item.class_ == 'warning' ? 'backBtnMargin' : 'btnMargin'"
          :type="item.class_"
          :icon="item.icon_"
          :loading="loading"
          >{{ item.text_ }}
        </a-button>
      </div>
    </div>

    <!-- 更多操作展开按钮 -->
    <a v-if="isEdit != true && pattern == 5" @click="clickBtn" class="ant-dropdown-link"
      ><a-icon v-if="btnClick" type="right" /><a-icon v-else type="left" />更多操作</a
    >
    <a-divider v-if="isEdit != true && pattern == 5" style="margin: 0 20px" type="vertical" />

    <!-- 编辑模式下显示 -->
    <template v-if="isEdit == true">
      <!-- 第二组按钮 -->
      <span v-if="stepBtnLoading == false && copyBtnList.length == 0">
        <a-button class="btnMargin" type="primary" icon="check" :loading="loading">审批通过 </a-button>
      </span>
      <span v-else>
        <!-- 配置环节预览 (编辑模式下用预览的, 处理模式用下调接口查的) -->
        <a-button
          v-for="(item, index) in copyBtnList"
          :key="index"
          class="custom_btn"
          :style="`background-color: ${item.class_};`"
          :icon="item.icon_"
          :loading="loading"
          >{{ item.text_ }}
        </a-button>
      </span>
    </template>

    <!-- 全局按钮第三组 -->
    <span v-if="btnLoading == false && isEdit != true">
      <a-button
        v-for="(item, index) in defaultBtnMap[3] ? defaultBtnMap[3] : []"
        @click="eventDistribution(item.click_)"
        :key="index"
        class="btnMargin"
        :style="`background-color: ${item.class_};`"
        :type="item.class_"
        :icon="item.icon_"
        :loading="loading"
        >{{ item.text_ }}
      </a-button>
    </span>

    <!-- 打开流程操作按钮模态框 -->
    <a-button
      v-if="isEdit != true"
      @click="opinionRecord()"
      class="btnMargin"
      :loading="loading"
      type="primary"
      icon="check"
      >处理</a-button
    >

    <!-- 常用语弹框 -->
    <operationModal
      v-if="processNext != null"
      ref="modalRef"
      :applyid="$route.params.applyid"
      :title="isTermination ? '中途办结' : '业务处理'"
      :processNext="processNext"
      :remark="ProcessNextExecutor.remark"
      :placeholder="`请填写${
        isTermination
          ? '中途办结原因（通常用于企业主动要求不办理，或审批下达通知后企业超期未响应。此操作无法还原请确认清楚！）'
          : '处理意见'
      }`"
      @f_setremark="s_setremark"
      :f_nextList="processNext.next"
      :taskObj="taskObj"
      @f_setTaskVariable="s_setTaskVariable"
    >
      <!-- 意见按钮插槽 -->
      <template slot="handleButton"> </template>
      <!-- 处理按钮插槽 -->
      <template slot="buttonList">
        <!-- 第二组按钮 -->
        <span v-if="stepBtnLoading == false && copyBtnList.length == 0 && isTermination == false">
          <a-button
            @click="eventDistribution('passRecord()')"
            class="btnMargin"
            type="primary"
            icon="check"
            :loading="loading"
            >审批通过
          </a-button>
        </span>
        <span v-else-if="isTermination">
          <a-button @click="handleOk()" class="btnMargin" type="primary" :loading="loading" icon="check"
            >确定
          </a-button>
        </span>
        <span v-else>
          <!-- 配置环节预览 (编辑模式下用预览的, 处理模式用下调接口查的) -->
          <a-button-group v-for="(item, index) in copyBtnList" :key="index" class="custom_btn">
            <a-button
              @click="eventDistribution(item.click_, item, true)"
              :style="`background-color: ${item.class_}; color: #fff;`"
              :icon="item.icon_"
              :loading="loading"
              >{{ item.text_ }}
            </a-button>
          </a-button-group>
        </span>
      </template>
    </operationModal>

    <!-- 人员树弹出层 -->
    <a-modal v-model="isEntrustModel" title="任务委托" destroyOnClose @ok="delegate(true)">
      <a-form-model>
        <a-form-model-item label="请选择委托人">
          <deptUserTree
            :departId="0"
            :type="'user'"
            :multiple="false"
            @save="treeSave"
            :filterOrgIds="['3601001001', '3601001002', '3601001003']"
          ></deptUserTree>
        </a-form-model-item>
      </a-form-model>
    </a-modal>

    <!-- 退回节点弹出层 -->
    <a-modal v-model="isBackModel" width="40%" title="业务退回" @ok="specifyBackRecord(true)">
      <a-select
        v-if="backSwitch"
        @change="handleChange"
        style="width: 100%; margin-bottom: 20px"
        placeholder="请选择退回节点"
      >
        <a-select-option v-for="item in backNodeList" :key="item.id" :value="item.id">
          {{ item.name }}
        </a-select-option>
      </a-select>
      <a-textarea v-model="backRemark" class="textareaBox" :placeholder="`请填写退回原因`" :max-length="300" />
    </a-modal>

    <!-- 通用意见 -->
    <WFMODAL ref="modalRemarkRef" @f_confirm="s_confirm">
      <div v-if="this.eventName == 'reassignRecord'" slot="head">
        <REASSIGNSELECT :pattern="pattern" @f_setAcceptsectionid="s_setAcceptsectionid" />
      </div>
    </WFMODAL>

    <ArriveNoticeModal
      ref="arriveNoticeModal"
      :applyid="$route.params.faapplyid || $route.params.applyid"
      @modalCancel="goBack"
    ></ArriveNoticeModal>
  </div>
</template>
<script>
import {
  taskExec,
  terminationTask,
  delegate,
  getTaskdefList,
  backProcess,
  findBehindTaskExecuser,
} from '@/api/workflow/mf_MyTaskUndo.js'
import { outProcess, saveVariable } from '@/api/workflow/wf_MyStartInstance.js'
import storage from 'store'
import { APP_USER, APP_DEPT } from '@/store/mutation-types'
import { queryAct_dsn_btnList } from '@/api/workflow/act_dsn_btn.js'
import { passRecordExecute } from '@/api/accept/process_approve.js'
import { YesNo } from '@/enumeration/YesNo.js'
import { queryAct_dsn_form_stepbtnList } from '@/api/workflow/act_dsn_form_stepbtn.js'
import { Tp_operation, Tp_business } from '@/enumeration/Tp_operation.js'
import { Tp_defaultvalue } from '@/enumeration/Tp_defaultvalue.js'
import moment from 'moment'
import { Form_FieldService } from '../../utils/formassembly/formfield.js'
import { customHandle } from '@/utils/custom/custom-handle.js'
import { Tp_categoryValue } from '@/enumeration/Tp_category.js'
import { CATEGORY_HIDDEN } from '@/utils/custom/custom-category.js'
export default {
  props: [
    'processinstanceid',
    'processdefinitionid',
    'taskid',
    'stepid',
    'formid',
    'owner',
    'taskName',
    'isStart',
    'isEdit',
    'btnList',
    'pattern',
    'category', // 流程状态
  ],
  data() {
    return {
      acceptsectionObj: null, // 变更拟受理单位存储id
      eventName: null, // 点击事件的名称
      btnVariable: null, // 按钮绑定的流程变量
      handleText: null, // 按钮操作文字
      btnServer: null, // 按钮配置服务
      Tp_operation: Tp_operation, // 环节按钮参数所做操作枚举
      stepBtnLoading: true, // 环节按钮查询状态
      copyBtnList: [], // 本页面的第二组按钮配置
      btnLoading: true, // 按钮加载状态
      defaultBtnMap: [], // 系统默认处理按钮配置
      btnClick: false,
      taskObj: {
        isNextPerson: false, // 是否需要或指定下一步的处理人 和
        isNextComplete: false, // 是否完成下一步处理人的指定
        taskVariab: {}, // 下一步处理人流程变量对象
      },
      processNext: null, // 下一环节的信息
      loading: false,
      backSwitch: false, // 退回时是否需要选择退回节点
      backRemark: '', // 退回原因
      backStepid: null, // 退回节点id
      backNodeList: [], // 可退回节点列表
      isBackModel: false,
      selectUserid: '', // 委托人usrid
      isEntrustModel: false, // 委托弹出层
      isTermination: false, // 是否处于终止状态
      currentUser: storage.get(APP_USER), // 登录人信息
      currentDept: storage.get(APP_DEPT), // 登录人部门
      // 完成对象
      ProcessNextExecutor: {
        remark: null, //审批意见
        taskFrom: {}, // 保存表单数据
        variable: {}, // 按钮关联的流程变量
        service: [], // 完成任务后调用的系统服务
      },
      pageInfo: {
        pageSize: 2147483647,
        sort: 'indexsort',
        order: 'ASC',
        f_formid_: this.$route.params.formid
      },
      CATEGORY_HIDDEN: CATEGORY_HIDDEN
    }
  },
  watch: {
    btnList(val) {
      this.copyList(val || [])
    },
  },
  created() {
    console.log('部门信息', this.currentDept)
    // 编辑模式下只查激活的按钮
    if (this.pattern == 3) {
      this.pageInfo.f_enable_ = YesNo[3200].value
    }
    console.log('按钮查询条件', this.pageInfo)

    if (this.stepid) {
      this.getFindBehindTaskExecuser()
      // 操作模式, 调父组件接口查询
    } else {
      // 编辑模式, 从父组件取值
      this.stepBtnLoading = false
      this.copyList(this.btnList || [])
    }
    this.getDefaultBtn()
  },
  methods: {
    // 子组件模态框确
    s_confirm(funName, remark, otherParams) {
      this[funName](remark, otherParams)
    },
    // 关闭子组件操作模态框
    closeModal() {
      this.$refs.modalRemarkRef.f_close()
    },
    // 显示子组件操作模态框
    shwoModal(title, funName, placeholder) {
      this.$refs.modalRemarkRef.f_init(title, funName, placeholder)
    },
    // 下一步处理人赋值
    s_setTaskVariable(data) {
      console.log('下一步处理人赋值', data)
      this.taskObj.taskVariab = data
      this.taskObj.isNextComplete = true
      this.opinionRecord()
    },
    // 处理弹框子组件回显意见
    s_setremark(remark) {
      // console.log('remark回显', remark)
      this.ProcessNextExecutor.remark = remark || ''
      // 给表单控件赋值
      Form_FieldService(this.ProcessNextExecutor.remark, this)
    },
    // 常用语弹框选中回显值
    s_popGetValue(value) {
      this.ProcessNextExecutor.remark = value
    },
    // 编辑模式下获取当前环节的按钮配置
    getStepBtnList(stepid) {
      this.pageInfo.f_stepid_ = stepid
      this.stepBtnLoading = true
      // console.log('查询条件', this.pageInfo)
      queryAct_dsn_form_stepbtnList(this.pageInfo)
        .then((res) => {
          console.log('环节按钮配置列表', res)
          if (res.code == 0) {
            this.copyBtnList = res.data.records || []
          }
        })
        .finally(() => {
          this.stepBtnLoading = false
        })
    },
    // 获取默认的配置按钮
    getDefaultBtn() {
      let _this = this
      this.btnLoading = true
      queryAct_dsn_btnList(this.pageInfo)
        .then((res) => {
          // console.log('系统默认按钮', res)
          if (res.code == 0) {
            res.data.records &&
              res.data.records.forEach((v) => {
                if (v.group_ in this.defaultBtnMap) {
                  this.defaultBtnMap[v.group_].push(v)
                } else {
                  this.defaultBtnMap[v.group_] = [v]
                }
              })
            if (this.CATEGORY_HIDDEN.includes(_this.category) && this.defaultBtnMap) {
              for (let count = 0; count < this.defaultBtnMap.length; count++) {
                let btnObj = this.defaultBtnMap[count]
                if (btnObj) {
                  this.defaultBtnMap[count] = btnObj.filter(
                    (el) => el.id != 'BTN_GETBACK' && el.id != 'BTN_BACK'
                  )
                }
              }
            }
            // console.log('系统默认按钮Map', this.defaultBtnMap)
          }
        })
        .finally(() => {
          this.btnLoading = false
        })
    },
    // 复制子组件第三组的按钮配置
    copyList(list) {
      this.copyBtnList = []
      list.forEach((v) => {
        let item = {}
        for (let key in v) {
          item[key] = v[key]
        }
        this.copyBtnList.push(v)
      })
    },
    // 配置的按钮事件中转函数 check是否触发二次校验
    eventDistribution(event, item, check = true) {
      if (this.isEdit == true) {
        return
      }
      if (item == undefined) {
        item = {}
      }
      if (event) {
        console.log('event', event, this.formid)
        let eventName = event.substring(0, event.indexOf('('))
        // ^ 存储到this上, 通用弹框组件判断要用
        this.eventName = eventName
        let eventValue = event.substring(event.indexOf('(') + 1, event.lastIndexOf(')'))
        eventValue = eventValue ? JSON.parse(eventValue) : {}
        // console.log('eventName', eventName)
        // console.log('eventValue', eventValue, typeof eventValue)

        // item 按钮配置对象
        // & 配置完成按钮要调用的服务
        this.btnServer = null
        if (item && item.postexecutors && JSON.parse(item.postexecutors).constructor === Array) {
          this.btnServer = item.postexecutors ? JSON.parse(item.postexecutors) : []
        }
        console.log('按钮配置', item)
        // 读取操作按钮文字
        this.handleText = item != undefined ? item.text_ : null

        // 读取按钮配置的流程变量
        if (item.variable) {
          try {
            this.btnVariable = eval(item.variable)
            console.log('按钮流程变量', eval(item.variable))
          } catch (error) {
            console.error(`解析按钮配置的流程变量失败:${error}`)
            this.$message.error('解析按钮配置的流程变量失败')
            return
          }
        }

        // return
        // 调用接口保存流程处理人变量
        if (JSON.stringify(this.taskObj.taskVariab) != '{}') {
          saveVariable(this.$route.params.processinstanceid, this.taskObj.taskVariab)
          console.log('流程处理人变量', this.taskObj.taskVariab)
        }
        switch (eventName) {
          case 'delegate':
            this.delegate(eventValue, item)
            break
          case 'suspendRecord':
            this.suspendRecord(eventValue, item)
            break
          case 'specifyBackRecord':
            this.specifyBackRecord(eventValue, item)
            break
          case 'terminationRecord':
            this.terminationRecord(eventValue, item)
            break
          case 'passRecord':
            this.passRecord(eventValue, item, check)
            break
          case 'backRecord':
            this.backRecord(eventValue, item)
            break
          default:
            this.$message.error('配置的处理事件不存在')
        }
      } else {
        this.$message.error('按钮未配置处理事件')
      }
    },
    // 子组件调用, 赋值变更后的受理单位
    s_setAcceptsectionid(acceptsectionObj) {
      this.acceptsectionObj = acceptsectionObj
    },
    // 更多的隐藏按钮展开
    clickBtn() {
      this.btnClick = !this.btnClick
    },
    // 退回弹框选择节点id
    handleChange(value) {
      console.log('退回到', value)
      this.backStepid = value
    },
    // 下一环节的处理人信息
    getFindBehindTaskExecuser() {
      this.processNext = null
      findBehindTaskExecuser({
        taskid: this.taskid,
        direction: 1,
      }).then((res) => {
        if (res.code === 0) {
          // console.log('下个环节信息', res)
          this.processNext = res.data || []
          if (this.processNext.exist) {
            this.processNext.next.forEach((v) => {
              v.assignee.forEach((assignee) => {
                if (assignee.indexOf('$') > -1) {
                  this.taskObj.isNextPerson = true
                }
              })
            })
          }
        }
      })
    },
    // 委托树保存
    treeSave(obj) {
      console.log('委托人', obj)
      if (obj.id) {
        this.selectUserid = obj.id
      } else {
        this.selectUserid = ''
      }
    },
    // 父表单组件调用, 给表单填写数据
    sSetFormData(body) {
      // 所有的流程变量
      this.ProcessNextExecutor.variable = { ...this.taskObj.taskVariab, ...this.btnVariable }
      this.ProcessNextExecutor.taskFrom = body || {}
      this.ProcessNextExecutor.handletext = this.handleText || null // 操作按钮的处理文字
      let params = {
        formid: this.formid,
        taskid: this.taskid,
        // 完成人员
        userid: this.currentUser.userId,
      }
      // console.log('params', params, this.ProcessNextExecutor)

      // ^ 取得表单数据配置调用服务
      if (this.btnServer != null && this.btnServer.length > 0) {
        // 转map给调用服务用
        let bodyMap = {}
        for (let table in body) {
          if (body[table].constructor === Array) {
            body[table].forEach((item) => {
              bodyMap[table + '#' + item.field] = item.value
            })
          }
        }
        this.configServe(this.btnServer, bodyMap)
      }
      console.log('完成', body, this.ProcessNextExecutor)

      // return
      // 完成业务接口
      this.loading = true
      const savem = this.$message.loading('正在执行操作，请稍后...', 0)
      taskExec(params, this.ProcessNextExecutor)
        .then((res) => {
          console.log('审批通过', res)
          if (res.code == 0 && res.data.code == 0) {
            this.$message.success('操作成功!')
            // 如果需要下载附件, 跳转到下载附件页面
            if (res.data && res.data.backParams && res.data.backParams.isAeliver) {
              this.arriveNoticeInit()
            } else {
              this.goBack()
            }
          } else {
            this.$message.warning(res.data.msg)
          }
        })
        .finally(() => {
          this.loading = false
          setTimeout(savem, 0)
        })
    },
    arriveNoticeInit () {
      this.$refs.arriveNoticeModal.init()
    },
    // 返回列表
    goBack() {
      // console.log('this.$route.query.url', this.$route.query.url)
      if (this.$route.query.url) {
        this.$router.push({
          path: this.$route.query.url,
          query: {
            queryParam: this.$route.query.queryParam,
          },
        })
      } else {
        this.$router.go(-1)
      }
    },
    // 显示处理弹框
    async opinionRecord() {
      // 如果是领导点击, 直接选择通过按钮
      if (customHandle(this)) {
        return
      }
      this.isTermination = false
      if (this.isEdit == true) {
        return
      }
      // 需要指定下一步的处理人
      this.$refs.modalRef.f_init()
    },
    // 通过操作
    async passRecord(eventValue, item = {}, check = true) {
      if (this.$route.params.category && this.$route.params.category in Tp_categoryValue) {
        const { data } = await passRecordExecute(
          this.$route.params.faapplyid || this.$route.params.applyid,
          this.$route.params.category
        )
        if (data.code != 0) {
          this.$emit('f_pointTab', '4')
          this.$message.warning(data.msg)
          return
        }
      }

      // & 配置按钮绑定的流程变量
      if (eventValue != null && eventValue.constructor === Object) {
        // $ 关联流程变量-服务
        if (item.type_ == Tp_operation['70301'].value) {
          for (let key in eventValue) {
            this.ProcessNextExecutor.variable[key.replace(/\s+/g, '')] = eventValue[key]
          }
          // console.log('按钮绑定的流程变量', this.ProcessNextExecutor.variable)
        }
      }
      let title = `确定${item.text_ ? item.text_ : '审批通过'}吗？`
      // 是否触二次校验
      if (check) {
        this.$confirm({
          title: title,
          okText: '确定',
          cancelText: '取消',
          zIndex: 2001,
          onOk: () => {
            // 4. 没有填意见就给按钮操作
            if (this.ProcessNextExecutor.remark == null || this.ProcessNextExecutor.remark.length == 0) {
              if (item.text_) {
                this.ProcessNextExecutor.remark = item.text_
              }
            }
            this.$emit('saveForm', true)
          },
        })
      } else {
        this.$emit('saveForm', true)
      }
    },
    // 调用配置服务
    configServe(serveList, bodyMap) {
      this.ProcessNextExecutor.service = []
      if (!serveList) {
        return
      }
      console.log('配置的服务', serveList)
      serveList.forEach((v) => {
        // console.log('服务对象', v, bodyMap)
        // 转化里面插值表达式的值
        for (let key in v) {
          if (typeof v[key] == 'string' && v[key].indexOf('${') > -1) {
            let result = []
            this.recursionExpression(result, v[key], bodyMap)
            v[key] = result.join('').replace(/(^\s*)|(\s*$)/g, '')
          }
        }
        let config = {
          name: v.service,
          bean: v.bean,
          params: v,
        }
        this.ProcessNextExecutor.service.push(config)
      })
    },
    // 递归转化插值表达式
    recursionExpression(variableArr = [], expression, bodyMap) {
      if (expression.indexOf('${') == -1) {
        return
      }
      const startIndex = expression.indexOf('${')
      const endIndex = expression.indexOf('}')
      variableArr.push(expression.substring(0, startIndex))
      const variable = expression.substring(startIndex + 2, endIndex).replace(/(^\s*)|(\s*$)/g, '')

      if (variable == 'remark') {
        // 如果表达式取输入的意见
        variableArr.push(this.ProcessNextExecutor.remark)
      } else if (variable == 'taskname') {
        // 如果表达式取环节名称
        variableArr.push(this.$route.params.taskName)
      } else if (variable == 'category') {
        // 如果环节分类
        variableArr.push(this.$route.params.category)
      } else if (variable in Tp_defaultvalue) {
        // 如果表达式是系统默认值
        variableArr.push(this.getSystemValue(variable))
      } else if (variable.indexOf('#') > -1 && variable in bodyMap) {
        // 如果表达式是表单上的属性 (子表格的数据取不到)
        variableArr.push(bodyMap[variable])
      }
      // console.log('表达式->', variableArr, variable, expression)
      // console.log('下一步', expression.substring(endIndex + 1, expression.length))
      this.recursionExpression(variableArr, expression.substring(endIndex + 1, expression.length), bodyMap)
    },
    // 获取系统配置表达式的默认值
    getSystemValue(value) {
      switch (value) {
        case 'user.fullname':
          return this.currentUser.fullname
        case 'user.id':
          return this.currentUser.userId
        case 'user.username':
          return this.currentUser.username
        case 'dept.id':
          return this.currentDept.id
        case 'dept.name':
          return this.currentDept.name
        case 'dept.sectionid':
          return this.currentDept.sectionid
        case 'dept.sectionname':
          return this.currentDept.sectionname
        case 'dept.adid':
          return this.currentDept.adid
        case 'now.date':
          return this.$moment().format('YYYY-MM-DD HH:mm:ss')
        case 'now.datetime':
          return this.$moment().format()
        case 'now.time':
          return this.$moment().format('HH:mm:ss')
        default:
          this.$message.error('未知的表达式' + value)
      }
    },
    // 退回操作
    backRecord() {
      this.backRemark = null
      this.backStepid = null
      this.backSwitch = false
      this.isBackModel = true
    },
    // 业务 - 终止
    businesstermination(eventValue) {
      let that = this
      let title = '中途办结'
      let content = '是否中途办结业务？'
      if (eventValue != null && eventValue.constructor === Object) {
        // 判断是否是预定义的业务操作
        if (eventValue?.business_ in Tp_business) {
          title = Tp_business[eventValue.business_].title
          content = Tp_business[eventValue.business_].content
        }
      }
      if (this.ProcessNextExecutor.remark == null || this.ProcessNextExecutor.remark.length == 0) {
        this.$message.warning(`请填写${title}意见`)
        return
      }
      this.$confirm({
        title: title,
        content: content,
        okText: '是',
        cancelText: '否',
        zIndex: 2001,
        onOk: () => {
          // 调用终止接口
          that.terminationInterface()
        },
        onCancel: () => {},
      })
    },
    // 终止操作 (有值说明是业务终止 没值是 系统终止)
    terminationRecord(eventValue, item) {
      if (eventValue && JSON.stringify(eventValue) != '{}') {
        this.businesstermination(eventValue)
      } else {
        // ^ (后面是系统终止)
        this.$refs.modalRef.f_init()
        this.isTermination = true
      }
    },
    // 委托操作
    delegate(state) {
      if (state == false) {
        this.selectUserid = ''
        this.isEntrustModel = true
      } else {
        // console.log('owner', this.owner)
        // 委托接口操作
        console.log('委托', this.selectUserid)
        if (this.selectUserid == '') {
          this.$message.warning('请先选择委托人')
          return
        } else if (this.selectUserid == this.currentUser.userId) {
          this.$message.warning('请不要选择自己')
          return
        }
        let params = {
          taskid: this.taskid,
          userid: this.currentUser.userId,
          entrustuserid: this.selectUserid,
        }
        const savem = this.$message.loading('正在执行操作，请稍后...', 0)
        delegate(params)
          .then((res) => {
            if (res.code === 0) {
              this.isEntrustModel = false
              this.$message.success('操作成功!')
              this.goBack()
            }
          })
          .finally(() => {
            setTimeout(savem, 0)
          })
      }
    },
    // 退回到指定节点
    specifyBackRecord(state) {
      console.log('退回至特定环节', state)
      if (state == false) {
        this.backRemark = null
        this.backSwitch = true
        // 获取可退回的节点
        getTaskdefList(this.stepid, this.processinstanceid).then((res) => {
          console.log('可退回节点', res)
          if (res.code == 0) {
            if (res.data && res.data.length > 0) {
              this.backNodeList = res.data
              this.backStepid = null
              this.isBackModel = true
            } else {
              this.$message.warning('没有可退回节点')
            }
          }
        })
      } else {
        if (this.backSwitch && this.backStepid == null) {
          this.$message.warning('请选择退回节点')
          return
        } else if (this.backRemark == null) {
          this.$message.warning('请填写退回原因')
          return
        }
        console.log('退回到', this.backStepid ? this.backStepid : '上一步')
        const savem = this.$message.loading('正在执行操作，请稍后...', 0)
        let body = {
          remark: this.backRemark,
          stepid: this.backStepid ? this.backStepid : '',
          taskid: this.taskid,
          handletext: this.handleText,
          variable: this.btnVariable,
          service: this.ProcessNextExecutor.service,
        }
        backProcess({ userid: this.currentUser.userId }, body)
          .then((res) => {
            if (res.code == 0 && res.data.code == 0) {
              this.$message.success('操作成功!')
              this.goBack()
            } else {
              this.$message.warning(res.data.msg)
            }
          })
          .finally(() => {
            setTimeout(savem, 0)
          })
      }
    },
    // 挂起操作
    async suspendRecord(eventValue, item) {
      console.log(eventValue, item)
      // 手动挂起走通用意见输入框
      if (JSON.stringify(eventValue) == '{}' && JSON.stringify(item) == '{}') {
        this.$refs.modalRemarkRef.f_init('业务挂起（挂起业务后将暂停执行）', 'suspendInterface', '请输入挂起原因')
        return
      }
      // 业务挂起走意见拼接
      let that = this
      let title = '业务挂起'
      let content = '挂起业务后将暂停执行，是否挂起？'
      // 判断是否是预定义的业务操作
      if (eventValue?.business_ in Tp_business) {
        title = Tp_business[eventValue.business_].title
        content = Tp_business[eventValue.business_].content
      }
      if (this.ProcessNextExecutor.remark == null || this.ProcessNextExecutor.remark.length == 0) {
        this.$message.warning(`请填写${title}意见`)
        return
      }
      this.$confirm({
        title: title,
        content: content,
        okText: '是',
        cancelText: '否',
        zIndex: 2001,
        onOk: () => {
          that.suspendInterface()
        },
        onCancel: () => {},
      })
    },
    // 挂起 (接口) (通用意见模态框确定过来的, remark 会有值)
    suspendInterface(remark = null) {
      // 调用服务
      this.configServe(this.btnServer, {})
      const savem = this.$message.loading('正在执行操作，请稍后...', 0)
      let parsms = {
        processinstanceid: this.processinstanceid,
        userid: this.currentUser.userId,
        suspensionState: 1,
        taskid: this.taskid,
      }
      let body = {
        service: this.ProcessNextExecutor.service,
        remark: remark || this.ProcessNextExecutor.remark,
        handletext: this.handleText, // 操作按钮的处理文字
        variable: this.btnVariable,
      }
      outProcess(parsms, body)
        .then((res) => {
          if (res.code == 0 && res.data.code == 0) {
            this.$message.success('操作成功!')
            this.goBack()
          } else {
            this.$message.warning(res.data.msg)
          }
        })
        .finally(() => {
          setTimeout(savem, 0)
          if (this.$refs.modalRef) {
            this.$refs.modalRef.f_close()
          }
        })
    },
    // 终止弹出层确定(系统按钮)
    handleOk() {
      this.$refs.modalRef.modalShow = false
      // 如果确认框处于终止状态, 走终止逻辑
      if (this.isTermination) {
        this.$refs.modalRef.f_init()
        if (this.ProcessNextExecutor.remark == null || this.ProcessNextExecutor.remark.length == 0) {
          this.$message.warning('请填写中途办结原因')
          return
        }
        // 调用终止接口
        this.terminationInterface()
      }
    },
    // 终止接口
    terminationInterface() {
      let params = {
        handletext: this.handleText, // 操作按钮的处理文字
        userid: this.currentUser.userId,
        taskid: this.taskid,
        deleteReason: this.ProcessNextExecutor.remark == '' ? '通过' : this.ProcessNextExecutor.remark,
      }
      console.log('终止', params)
      // 调用服务
      this.configServe(this.btnServer, {})
      const savem = this.$message.loading('正在执行操作，请稍后...', 0)
      terminationTask(params, this.ProcessNextExecutor.service)
        .then((res) => {
          if (res.code == 0 && res.data.code == 0) {
            this.$message.success('操作成功!')
            this.handleNo()
            this.goBack()
          } else {
            this.$message.warning(res.data.msg)
          }
        })
        .finally(() => {
          setTimeout(savem, 0)
        })
    },
    // 弹出层隐藏
    handleNo() {
      this.ProcessNextExecutor.remark = null
      this.$refs.modalRef.modalShow = false
      this.isTermination = false
    },
  },

  components: {
    deptUserTree: () => import('@/views/base/DeptUserTree.vue'),
    ComwordPop: () => import('@/views/base/Std_comwordPop.vue'),
    operationModal: () => import('@/views/workflow/Wf_FormOperationModal.vue'),
    WFMODAL: () => import('@/views/base/Wf_Modal.vue'),
    REASSIGNSELECT: () => import('@/views/operationComponents/reassignSelect.vue'),
    ArriveNoticeModal: () => import('@/views/arrive/ArriveNoticeModal.vue'),
  },
}
</script>
<style lang="less" scoped>
.poppverBox {
  height: 10px;
}

// --- 按钮 --
.backBtnMargin,
.btnMargin {
  margin-left: 10px;
}
.backBtnMargin {
  color: #fff;
  background-color: #f9ae3d;
}
// ant-D 自定义按钮颜色伪类 (默认成功) xiaohao
.backBtnMargin:hover,
.backBtnMargin:focus {
  background-color: #f9ae3d; //#1fdb18;
  opacity: 0.8;
  color: #fff;
  border: 1px solid #ccc;
}
.custom_btn,
.btnMargin {
  margin-left: 10px;
}

.custom_btn {
  color: #fff;
  border: 1px solid #ccc;
  border: none;
}
.custom_btn:hover,
.custom_btn:focus {
  opacity: 0.8;
  color: #fff;
  border: none;
}

// --- 按钮 ---

.animationBox {
  overflow: hidden;
  .outCOn {
    width: 0px;
    white-space: nowrap;
    background: #fff;
    // background-color: #fff;
  }
  .outClick {
    display: flex;
    justify-content: flex-end;
    // border: 1px solid red;
    transition: all 0.2s linear;
  }
  .dieClick {
    width: 0px;
    transition: all 0.2s linear;
  }
}

.buttonBox {
  width: 100%;
  background-color: #fff;
  position: fixed;
  bottom: 0px;
  right: 0;
  height: 60px;
  box-shadow: 1px 1px 10px rgba(49, 45, 45, 0.377);
  display: flex;
  justify-content: flex-end;
  align-items: center;
  padding-right: 5%;
  z-index: 9;
}
.textareaBox {
  height: 150px;
  /* margin-top: 20px; */
}
</style>
